home *** CD-ROM | disk | FTP | other *** search
- (*
- * :Program. Tapete.mod
- * :Author. Fridtjof Siebert
- * :Address. Nobileweg 67, D-7000 Stuttgart 40
- * :Shortcut. [fbs]
- * :Copyright. FreeWare
- * :Language. Oberon-2
- * :Translator. Amiga Oberon Compiler V2.30 (inoffical version)
- * :History. V1.0 02-Mar-92: first published version [fbs]
- * :Contents. Tool to replace WBPattern by an arbitrary image
- * :Usage. Tapete <picture> [SAMECOLORS]
- * :Remark. Compile: 'Oberon -m Tapete', don't use small data model!
- * :Remark. Link: 'OLink -s Tapate OBJ LoadBody.o'
- *
- *
- *
- * Bitte nur mit großem Datenmodell:
- *
- * $IFNOT SmallData
- *
- *)
-
- MODULE Tapete;
-
- IMPORT Exec,
- Graphics,
- SYSTEM,
- Dos,
- OberonLib,
- Strings,
- IFFSupport,
- Arguments;
-
-
- (*-------------------------------------------------------------------------*)
-
-
- TYPE
- BP = PROCEDURE (rp{9} : Graphics.RastPortPtr;
- mask{8} : Graphics.PLANEPTR;
- xMin{0} : INTEGER;
- yMin{1} : INTEGER;
- xMax{2} : INTEGER;
- yMax{3} : INTEGER;
- bytecnt{4} : INTEGER);
- (*
- * Typ der BltPattern()-Prozedur
- *)
-
- VAR
- OldBP: BP;
- (*
- * Original BltPattern-Prozedur.
- *)
-
-
- (*-------------------------------------------------------------------------*)
-
-
- TYPE
- PatPlane = ARRAY 16 OF INTEGER;
- PatPlanePtr = UNTRACED POINTER TO PatPlane;
- (*
- * Typen für WB-AreaPattern
- *)
-
- OldPat = STRUCT
- weissnich: ARRAY 9 OF INTEGER;
- pad: SHORTINT;
- depth: SHORTINT;
- data: ARRAY 8 OF PatPlane; (* eigentlich: ARRAY depth OF PatPlane *)
- END;
- (*
- * Inhalt von ENV:sys/wb.pat
- *)
-
- CONST
- IdentifyPattern =
- PatPlane(0162FU,0F5A2U,0A18AU,00D66U,0FD1AU,07F9CU,0E15AU,05265U,
- 0C5C9U,06460U,0494FU,0E5DBU,0BC61U,0FF7BU,01510U,09432U);
- (*
- * Durch Zufallszahlen erzeugtes Muster. Dieses wird verwendet, um die
- * BltPattern-Aufrufe der Workbench zu identifizieren. Immer, wenn ein mit
- * Rechteck diesem Muster gefüllt wird, wird stattdessen das Bild gezeichnet.
- *)
-
-
- (*-------------------------------------------------------------------------*)
-
-
- VAR
-
- f: Dos.FileHandlePtr; (* Generelles FileHandle zum Laden und Speichern. *)
-
- oldwbpat, wbpat: OldPat; (* Altes und neues ENV:sys/wb.pat *)
- restoreWBPat: BOOLEAN; (* Muß bei CLOSE ENV:sys/wb.pat neu geschrieben werden? *)
- WBPatSize: LONGINT; (* Größe von oldwbpat *)
-
- size: LONGINT; (* verschieden verendet, größe von Dateien *)
-
- s,w: SYSTEM.ADDRESS; (* Dummys für IFFSupport.ReadILBM() *)
-
- Image: Graphics.BitMapPtr; (* Geladenes Bild *)
-
- i: INTEGER; (* Durchwandern der Argumente, Farben und Planes *)
-
- arg,Pic: ARRAY 256 OF CHAR;(* Akutuelles Argument, Name des Bildes *)
-
- SameColors: BOOLEAN; (* ist SAMECOLORS angegeben? *)
-
- color: ARRAY 3 OF BYTE; (* Zum Speichern der Farben *)
- ColorSize: LONGINT; (* Zum Speichern von ENV:sys/palette.ilbm *)
- CMAPSize: LONGINT; (* dito *)
-
- OldPalette: ARRAY 512 OF CHAR; (* Vorheriger Inhalt von ENV:sys/palette.ilbm *)
- restorePalette: BOOLEAN; (* Muß bei CLOSE ENV:sys/palette.ilbm neu geschrieben werden? *)
- PaletteSize: LONGINT; (* Gröe von OldPalette *)
-
- port: Exec.MsgPortPtr; (* MessagePort, zum Prüfen, ob Tapete schon gestartet wurde *)
-
-
- (*-------------------------------------------------------------------------*)
-
-
- PROCEDURE FillWithImage(rp:Graphics.RastPortPtr; x,y,X,Y: INTEGER); (* $Debug- $StackChk- *)
- (*
- * Zeichnet Image in rp in das Rechteck (x,y),(X,Y).
- *
- * Ist der Bereich größer als das Bild selbst, wird das Bild stückchenweise
- * gezeichnet.
- *
- *)
-
- VAR
- width,height,w,h,startx,starty,Imagex,Imagey: INTEGER;
-
- BEGIN
- height := Y-y+1;
- starty := y;
- Imagey := starty MOD IFFSupport.NuScreen.height;
-
- WHILE height>0 DO
-
- h := IFFSupport.NuScreen.height - Imagey;
- IF h>height THEN h := height END;
-
- width := X-x+1;
- startx := x;
- Imagex := startx MOD IFFSupport.NuScreen.width;
-
- WHILE width>0 DO
-
- w := IFFSupport.NuScreen.width - Imagex;
- IF w>width THEN w := width END;
-
- Graphics.BltBitMapRastPort(Image,Imagex,Imagey,rp,startx,starty,w,h,0C0X);
-
- DEC(width,w);
- INC(startx,w);
- Imagex := 0;
-
- END;
-
- DEC(height,h);
- INC(starty,h);
- Imagey := 0;
-
- END;
- END FillWithImage;
-
-
- PROCEDURE CheckPtrn(p: PatPlanePtr): BOOLEAN; (* $StackChk- *)
- (*
- * Prüft, ob p#NIL und p^ gleich dem IdentifyPattern ist.
- * Dabei wird auch berücksichtigt, daß p^ evtl. vertikal
- * verschoben wurde.
- *)
-
- VAR
- y,i: INTEGER;
-
- BEGIN
- IF p#NIL THEN
- y := 0;
- WHILE (y<16) & (p[0]#IdentifyPattern[y]) DO INC(y) END;
- IF y<16 THEN
- i := 0;
- WHILE IdentifyPattern[y]=p[i] DO
- INC(i);
- y := (y+1) MOD 16;
- IF i=16 THEN RETURN TRUE END;
- END;
- END;
- END;
- RETURN FALSE;
- END CheckPtrn;
-
-
-
- PROCEDURE NewBltPattern (rp{9} : Graphics.RastPortPtr; (* $SaveRegs+ $StackChk- *)
- mask{8} : Graphics.PLANEPTR;
- xMin{0} : INTEGER;
- yMin{1} : INTEGER;
- xMax{2} : INTEGER;
- yMax{3} : INTEGER;
- bytecnt{4} : INTEGER);
- (*
- * Neue, mit SetFunction aktivierte BltPattern()-Routine.
- *)
-
- VAR
- xm,ym: INTEGER;
-
- BEGIN
- xm := xMin; ym := yMin;
- IF CheckPtrn(rp.areaPtrn) THEN
- FillWithImage(rp,xm,ym,xMax,yMax);
- ELSE
- OldBP(rp,mask,xm,ym,xMax,yMax,bytecnt);
- END
- END NewBltPattern; (* $StackChk+ $Debug= *)
-
-
- (*-------------------------------------------------------------------------*)
-
-
- BEGIN
-
- (*
- * 2.0 only:
- *)
-
- IF Dos.dos.lib.version<37 THEN HALT(20) END;
-
-
- (*
- * zunächst wird geprüft, ob wir schon einmal gestartet wurden:
- *)
-
- Exec.Forbid;
- port := Exec.FindPort("Tapeziertisch");
- IF port#NIL THEN
- Exec.Signal(port.sigTask,LONGSET{Dos.ctrlC});
- port := NIL;
- Exec.Permit;
- Dos.PrintF("Signalled Tapete to quit.\n");
- HALT(0);
- ELSE
- INCL(OberonLib.MemReqs,Exec.public);
- NEW(port);
- EXCL(OberonLib.MemReqs,Exec.public);
- IF port=NIL THEN
- Exec.Permit;
- Dos.PrintF("Out of memory!\n");
- HALT(20);
- END;
- port.node.name := SYSTEM.ADR("Tapeziertisch");
- port.node.type := Exec.msgPort;
- port.flags := Exec.signal;
- port.sigTask := Exec.exec.thisTask;
- Exec.AddPort(port)
- END;
- Exec.Permit;
-
-
- (*
- * Nun werden die Argumente ausgewertet:
- *)
-
- FOR i:=1 TO Arguments.NumArgs() DO
-
- Arguments.GetArg(i,arg);
-
- Strings.Upper(arg);
- IF arg="SAMECOLORS" THEN
-
- SameColors := TRUE
-
- ELSE
-
- Arguments.GetArg(i,Pic);
-
- END;
-
- END;
-
- IF (Pic="") OR (Pic="?") THEN
-
- Dos.PrintF("Usage: Tapete <Picture> [SAMECOLORS]\n");
- HALT(5);
-
- END;
-
-
- (*
- * Das Bild wird geladen:
- *)
-
- IF ~ IFFSupport.ReadILBM(Pic,{IFFSupport.usebmsize,IFFSupport.dontopen,IFFSupport.visible},s,w) THEN
-
- Dos.PrintF("Couldn't load %s!\n",SYSTEM.ADR(Pic));
- HALT(20);
-
- END;
- Image := IFFSupport.NuScreen.customBitMap;
-
-
- (*
- * Neue Palette setzen:
- *)
-
- IF ~ SameColors THEN
-
- f := Dos.Open("ENV:sys/palette.ilbm",Dos.oldFile);
- IF f=NIL THEN Dos.PrintF("ENV:sys/palette.ilbm not found!\n"); HALT(20) END;
-
- PaletteSize := Dos.Read(f,OldPalette,SIZE(OldPalette));
- IF ~ Dos.Close(f) OR (PaletteSize<=0) THEN
- Dos.PrintF("Error Reading ENV:sys/palette.ilbm!\n");
- HALT(20);
- END;
-
- restorePalette := TRUE;
-
- f := Dos.Open("ENV:sys/palette.ilbm",Dos.newFile);
- IF f=NIL THEN Dos.PrintF("Couldn't open ENV:sys/palete.ilbm!\n"); HALT(20) END;
-
- CMAPSize := 3*IFFSupport.IFFInfo.CMAP.colorCnt;
- IF ODD(CMAPSize) THEN INC(CMAPSize) END;
- ColorSize := CMAPSize + 56;
-
- size := Dos.Write(f,"FORM" ,4) +
- Dos.Write(f,ColorSize,4) +
- Dos.Write(f,"ILBMBMHD"
- "\x00\x00\x00\x14\x00\x10\x00\x01\x00\x00\x00\x00\x04\x00\x00\x00"
- "\x00\x00\x0A\x0B\x01\x40\x00\xC8CMAP",36) +
- Dos.Write(f,CMAPSize,4);
- FOR i := 0 TO IFFSupport.IFFInfo.CMAP.colorCnt - 1 DO
- color[0] := CHR(LONG(IFFSupport.IFFInfo.CMAP.red [i])*16);
- color[1] := CHR(LONG(IFFSupport.IFFInfo.CMAP.green[i])*16);
- color[2] := CHR(LONG(IFFSupport.IFFInfo.CMAP.blue [i])*16);
- INC(size,Dos.Write(f,color,3));
- END;
- IF ODD(IFFSupport.IFFInfo.CMAP.colorCnt) THEN
- INC(size,Dos.Write(f,"\x00",1));
- END;
- INC(size,Dos.Write(f,"BODY\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00",16));
-
- IF ~ Dos.Close(f) OR (size#ColorSize+8) THEN
- Dos.PrintF("Error writing ENV:sys/palette.ilbm!\n");
- HALT(20);
- END;
-
- END;
-
-
- (*
- * Neue BltPattern()-Routine aktivieren:
- *)
-
- OldBP := SYSTEM.VAL(BP,Exec.SetFunction(Graphics.gfx,-312,SYSTEM.VAL(Exec.PROC,NewBltPattern)));
-
-
- (*
- * Altes ENV:sys/wb.pat laden:
- *)
-
- f := Dos.Open("ENV:sys/wb.pat",Dos.oldFile);
- IF f=NIL THEN Dos.PrintF("ENV:sys/wb.pat not found!\n"); HALT(20) END;
-
- WBPatSize := Dos.Read(f,wbpat,SIZE(wbpat));
- IF ~ Dos.Close(f) OR (WBPatSize<52) THEN
- Dos.PrintF("Error Reading ENV:sys/wb.pat!\n");
- HALT(20);
- END;
- oldwbpat := wbpat;
-
-
- (*
- * Neues ENV:sys/wb.pat speichern:
- *)
-
- wbpat.data[0] := IdentifyPattern;
- restoreWBPat := TRUE;
-
- f := Dos.Open("ENV:sys/wb.pat",Dos.newFile);
- IF f=NIL THEN Dos.PrintF("Couldn't open ENV:sys/wb.pat!\n"); HALT(20) END;
-
- size := WBPatSize - Dos.Write(f,wbpat,WBPatSize);
- IF ~ Dos.Close(f) OR (size#0) THEN
- Dos.PrintF("Error writing ENV:sys/wb.pat!\n");
- HALT(20);
- END;
-
-
- (*
- * Warten, bis man uns nicht mehr will:
- *)
-
- REPEAT UNTIL Dos.ctrlC IN Exec.Wait(LONGSET{Dos.ctrlC});
-
- CLOSE
-
-
- (*
- * ENV:sys/palette.ilbm zurückschreiben:
- *)
-
- IF restoreWBPat THEN
- f := Dos.Open("ENV:sys/wb.pat",Dos.newFile);
- IF f=NIL THEN
- Dos.PrintF("Couldn't open ENV:sys/wb.pat!\n")
- ELSE
- DEC(WBPatSize,Dos.Write(f,oldwbpat,WBPatSize));
- IF ~ Dos.Close(f) OR (WBPatSize#0) THEN
- Dos.PrintF("Error writing ENV:sys/wb.pat!\n");
- END;
- END;
- END;
-
-
- (*
- * ENV:sys/wb.pat zurückschreiben:
- *)
-
- IF restorePalette THEN
- f := Dos.Open("ENV:sys/palette.ilbm",Dos.newFile);
- IF f=NIL THEN
- Dos.PrintF("Couldn't open ENV:sys/palete.ilbm!\n")
- ELSE
- DEC(PaletteSize,Dos.Write(f,OldPalette,PaletteSize));
- IF ~ Dos.Close(f) OR (PaletteSize#0) THEN
- Dos.PrintF("Error writing ENV:sys/palette.ilbm!\n");
- END;
- END;
- END;
-
-
- (*
- * BltPattern wieder auf alte Routine setzen.
- *
- * ACHTUNG: Hier wird nicht geprüft, ob ein anderes Programm unterdessen
- * BltPattern mit SetFunction() verändert hat. Ist dies der Fall, stürzt
- * die Maschine ab.
- *)
-
- IF OldBP # NIL THEN
- IF Exec.SetFunction(Graphics.gfx,-312,SYSTEM.VAL(Exec.PROC,OldBP))=NIL THEN END;
- END;
-
-
- (*
- * Speicher für Bild freigeben:
- *)
-
- IF Image#NIL THEN
- FOR i:=0 TO Image.depth-1 DO
- Graphics.FreeRaster(Image.planes[i],IFFSupport.NuScreen.width,IFFSupport.NuScreen.height);
- END;
- DISPOSE(Image);
- END;
-
-
- (*
- * Port schließen:
- *)
-
- IF port#NIL THEN Exec.RemPort(port) END;
-
- END Tapete.
-
- (* $END *)
-